package jp.sourceforge.talisman.mds.cluster;

/*
 * $Id: ClusteringMethodFactory.java,v 1.1 2009/09/12 05:06:01 weiwei Exp $
 */

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Map;

/**
 * 
 * @author Haruaki Tamada
 * @version $Revision: 1.1 $ 
 */
public class ClusteringMethodFactory{
    private static final ClusteringMethodFactory instance = new ClusteringMethodFactory();

    private Map<ClusteringAlgorithm, Class<? extends ClusteringMethod>> map = new HashMap<ClusteringAlgorithm, Class<? extends ClusteringMethod>>();

    private ClusteringMethodFactory(){
        map.put(ClusteringAlgorithm.EXCHANGE_METHOD, ExchangeMethod.class);
        map.put(ClusteringAlgorithm.PARALLEL_HCM, ParallelHardCMeanMethod.class);
        map.put(ClusteringAlgorithm.SEQUENTIAL_HCM, SequentialHardCMeanMethod.class);
        map.put(ClusteringAlgorithm.HIERARCHICAL_METHOD, HierarchicalClusteringMethod.class);
        map.put(ClusteringAlgorithm.LANCE_AND_WILLIAMS_METHOD, LanceWilliamsClusteringMethod.class);
    }

    public static ClusteringMethodFactory getInstance(){
        return instance;
    }

    public ClusteringMethod getAlgorithm(ClusteringAlgorithm algorithm, ClusteringParameter param) throws ParameterTypeMismatchException{
        try{
            Class<? extends ClusteringMethod> clazz = map.get(algorithm);
            Constructor<? extends ClusteringMethod> constructor = clazz.getConstructor(ClusteringParameter.class);

            return constructor.newInstance(param);

        } catch(InvocationTargetException e){
            Throwable cause = e.getCause();
            if(cause instanceof ParameterTypeMismatchException){
                throw (ParameterTypeMismatchException)cause;
            }
            else if(cause instanceof NullPointerException){
                throw (NullPointerException)cause;
            }
            throw new InternalError(e.getMessage());
        } catch(Exception e){
            throw new InternalError(e.getMessage());
        }
    }
}
